package com.jeesite.modules.digitalize.util.mpp;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.mpxj.ProjectFile;
import net.sf.mpxj.Relation;
import net.sf.mpxj.Task;
import net.sf.mpxj.TaskContainer;
import net.sf.mpxj.mpp.MPPReader;
import net.sf.mpxj.writer.ProjectWriter;
import net.sf.mpxj.writer.ProjectWriterUtility;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;

/**
 * @author zhaoshuaixiang
 * @date 2023/11/16 11:55
 */
@Slf4j
public class MppUtil {

    public static void exportProjectFile(HttpServletResponse response,ProjectFile projectFile, String filePath) {
        try {
            // 使用 ProjectWriterUtility 创建一个 ProjectWriter
            ProjectWriter writer = ProjectWriterUtility.getProjectWriter(filePath);
//            // 使用 ProjectWriter 将数据写入文件
//            writer.write(projectFile, filePath);


            writer.write(projectFile,response.getOutputStream());

            System.out.println("Project 文件成功导出到: " + filePath);
        } catch (Exception e) {
            log.error("Project导出失败", e);
            throw new RuntimeException("Project导出失败");
        }
    }


    /**
     * 解析mpp文件
     *
     * @param file 文件
     * @return 解析后的数据
     */
    public static List<TaskInfoVo> analysisMpp(MultipartFile file) {
        List<TaskInfoVo> taskInfoVos = readFile(file);
        if (taskInfoVos == null) {
            return new ArrayList<>();
        }
        return refreshTaskInfo(taskInfoVos);
    }

    private static List<TaskInfoVo> readFile(MultipartFile file) {
        List<TaskInfoVo> taskList = new ArrayList<TaskInfoVo>();
        try {
            //1. 读取文件
            MPPReader mppRead = new MPPReader();
            ProjectFile pf = mppRead.read(file.getInputStream());
            TaskContainer tasks1 = pf.getTasks();
            //2. 拿到task对象
            // List<Task> tasks = pf.getAllTasks();
            //3. 遍历task对象，找到其中的值
            for (Task task : tasks1) {
                Integer task_id = task.getID();
                Integer task_unique_id = task.getUniqueID();
                Integer task_outline_level = task.getOutlineLevel();
                double task_duration = task.getDuration().getDuration();
                Date task_start_date = task.getStart();
                Date task_finish_date = task.getFinish();
                List<Relation> task_predecessors = task.getPredecessors();
                Date actualStart = task.getActualStart();
                Date actualFinish = task.getActualFinish();

                //4. 获取前置任务（任务流）
                StringBuilder beforeTaskId = new StringBuilder();
                StringBuilder beforeTaskType = new StringBuilder();
                if (CollUtil.isNotEmpty(task_predecessors)) {
                    for (Relation relation : task_predecessors) {
                        Integer targetTaskId = relation.getTargetTask().getID();
                        if (beforeTaskId.length() == 0) {
                            beforeTaskId.append(targetTaskId);
                            beforeTaskType.append(relation.getType());
                        } else {
                            beforeTaskId.append(",").append(targetTaskId);
                            beforeTaskType.append(",").append(relation.getType());
                        }
                    }
                }
                String task_predecessors_str = beforeTaskId.toString();
                String task_predecessors_str_type = beforeTaskType.toString();
                //5. 给taskinfo实体类赋值
                TaskInfoVo taskInfo = new TaskInfoVo();
                taskInfo.setTaskId(task_id);
                taskInfo.setTaskUniqueId(task_unique_id);
                taskInfo.setTaskOutlineLevel(task_outline_level);
                taskInfo.setTaskDuration(task_duration);
                taskInfo.setTaskStartDate(DateUtil.parse(DateUtil.format(task_start_date, DatePattern.NORM_DATE_PATTERN)));
                taskInfo.setTaskFinishDate(DateUtil.parse(DateUtil.format(task_finish_date, DatePattern.NORM_DATE_PATTERN)));
                taskInfo.setTaskPredecessors(task_predecessors_str);
                taskInfo.setTaskType(task_predecessors_str_type);
                taskInfo.setTaskName(task.getName());
                taskInfo.setActualStart(DateUtil.parse(DateUtil.format(actualStart, DatePattern.NORM_DATE_PATTERN)));
                taskInfo.setActualFinish(DateUtil.parse(DateUtil.format(actualFinish, DatePattern.NORM_DATE_PATTERN)));

                //6.自定义列读取
//                String task_operator = task.getText(2);
//                taskInfo.setTask_operator(task_operator);
                taskList.add(taskInfo);
            }
        } catch (Exception e) {
            return null;
        }
        return taskList;
    }


    // NO.2 获取TaskInfo之间的父子关联关系
    private static List<TaskInfoVo> refreshTaskInfo(List<TaskInfoVo> taskList) {
        List<Map<String, Integer>> tempTaskOutLine = new ArrayList<Map<String, Integer>>();
        for (TaskInfoVo taskInfo : taskList) {
            int taskId = taskInfo.getTaskId();
            int taskOutLineLevel = taskInfo.getTaskOutlineLevel();
            int listSize = tempTaskOutLine.size();
            // 初始化taskOutLineLevel
            if (listSize > 2) {
                if (taskOutLineLevel == 1) {
                    for (int i = listSize; i > 2; i--) {
                        tempTaskOutLine.remove(i - 1);
                    }
                    listSize = 2;
                }
            }
            Map<String, Integer> map = new HashMap<String, Integer>();
            map.put("taskId", taskId);
            map.put("taskOutLineLevel", taskOutLineLevel);
            if (listSize == 0) {
                if (taskOutLineLevel == 0) {
                    tempTaskOutLine.add(map);
                } else {
                    return null;
                }
            } else {
                Map<String, Integer> lastMap = tempTaskOutLine.get(listSize - 1);
                Integer lastTaskId = lastMap.get("taskId");
                int lastTaskOutLineLevel = lastMap.get("taskOutLineLevel");
                if (taskOutLineLevel > lastTaskOutLineLevel) {
                    tempTaskOutLine.add(map);
                    taskInfo.setParentId(lastTaskId);
                } else if (taskOutLineLevel == lastTaskOutLineLevel) {
                    tempTaskOutLine.set(taskOutLineLevel, map);
                    Map<String, Integer> lastMap1 = tempTaskOutLine.get(taskOutLineLevel - 1);
                    Integer lastTaskId1 = lastMap1.get("taskId");
                    taskInfo.setParentId(lastTaskId1);
                } else {
                    tempTaskOutLine.set(taskOutLineLevel, map);
                    Map<String, Integer> lastMap2 = tempTaskOutLine.get(taskOutLineLevel - 1);
                    Integer lastTaskId2 = lastMap2.get("taskId");
                    taskInfo.setParentId(lastTaskId2);
                }
            }
        }
        taskList.remove(0);
        return taskList;
    }

}
